package com.example.interactservice.serviceImpl;

import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.commom.enums.StatusCodeEnum;
import com.example.commom.exception.CustomException;
import com.example.commom.global.AppVariable;
import com.example.commom.utils.JwtUtils;
import com.example.feign.result.AjaxResult;
import com.example.interactservice.entity.BookReviewsBranch;
import com.example.interactservice.entity.BookReviewsRoot;
import com.example.interactservice.mapper.BookReviewsBranchMapper;
import com.example.interactservice.service.BookReviewsBranchService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Random;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 软工2104-李家强-2100770248
 * @since 2023-09-21
 */
@Slf4j
@Service
@Transactional
public class BookReviewsBranchServiceImpl extends ServiceImpl<BookReviewsBranchMapper, BookReviewsBranch> implements BookReviewsBranchService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private BookReviewsBranchService bookReviewsBranchService;

    /**
     * 获取指定书籍指定章节指定主评论的所有子评论
     */
    public List<BookReviewsBranch> getAllBranchReviews(Long targetBook, Long targetChapter,
                                                       Long targetRootReview, String userId) {
        LambdaQueryWrapper<BookReviewsBranch> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 随机按照 点赞和最新 排序
        Random random = new Random();
        int number = random.nextInt(10);

        lambdaQueryWrapper.eq(BookReviewsBranch::getBookId, targetBook)
                .eq(BookReviewsBranch::getChapterId, targetChapter)
                .eq(BookReviewsBranch::getReviewRootId, targetRootReview);
        if (number % 2 == 0) {
            // 发布时间 最新排序.
            lambdaQueryWrapper.orderByAsc(BookReviewsBranch::getReviewDate);
        } else {
            // 点赞数目 从高到低 排序
            lambdaQueryWrapper.orderByDesc(BookReviewsBranch::getPrizeCount);
        }

        List<BookReviewsBranch> result = bookReviewsBranchService.list(lambdaQueryWrapper);

        result.forEach(item -> {
            this.isReviewLiked(item, userId);
        });

        return result;
    }

    /**
     *  插入一条子评论
     */
    public boolean insertBranchReview(BookReviewsBranch bookReviewsBranch) {

        bookReviewsBranch.setReviewId(null);
        bookReviewsBranch.setPrizeCount(null);
        bookReviewsBranch.setReviewDate(null);

        boolean success = bookReviewsBranchService.save(bookReviewsBranch);

        if (success) {
            return true;
        } else {
            throw new CustomException(StatusCodeEnum.FAILED.getMsg(), -1);
        }
    }

    @Override
    public AjaxResult likeReview(Long targetId, String token) {

        // 1. 拿到登录用户的id
        String userIdByToken = JwtUtils.getUserIdByToken(token);

        if (userIdByToken == null) {
            return AjaxResult.fail(StatusCodeEnum.Redirect.getCode(), StatusCodeEnum.Redirect.getMsg());
        }

        // 2. 判断当前用户是否已经点赞
        String key = "reviewBranch:like:" + targetId;
        Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userIdByToken);

        if (BooleanUtil.isFalse(isMember)) {
            // 3. 未点赞, 就可以点赞
            // 3.1 点赞数目 +1
            boolean success = update().setSql("prize_count = prize_count + 1")
                    .eq("review_id", targetId).update();

            if (success) {
                // 3.2 将用户保存到 redis 的 set 集合中.
                stringRedisTemplate.opsForSet().add(key, userIdByToken);
            }
        } else {
            // 4. 已经点赞, 那就是取消点赞
            boolean success = update().setSql("prize_count = prize_count - 1")
                    .eq("review_id", targetId).update();

            if (success) {
                // 3.2 将用户从 redis 的 set 集合中移除.
                stringRedisTemplate.opsForSet().remove(key, userIdByToken);
            }
        }

        return AjaxResult.success(StatusCodeEnum.OK.getMsg());
    }

    /**
     *  通过 id 获取 子评论信息
     * @param bookReviewsBranchId 子评论 id
     * @return 子评论对象
     */
    @Override
    public BookReviewsBranch getReviewById(Long bookReviewsBranchId, String userId) {
        BookReviewsBranch result = getById(bookReviewsBranchId);

        if (result == null) {
            return null;
        }

        this.isReviewLiked(result, userId);
        return result;
    }

    /**
     *  判断评论是否已经被点赞
     */
    private void isReviewLiked(BookReviewsBranch bookReviewsBranch, String userId) {

        // 判断当前用户是否已经点赞
        String key =  "reviewBranch:like:" + bookReviewsBranch.getReviewId();
        Boolean isMember = stringRedisTemplate.opsForSet().isMember(key, userId);

        bookReviewsBranch.setLike(BooleanUtil.isTrue(isMember));
    }

}
